package com.ddstation.statement.service;

import java.util.*;
import java.util.stream.Collectors;

import javax.inject.Inject;

import com.ddstation.home_page.model.NameValueModel;
import com.ddstation.statement.constant.IllegalDailyCheckEnum;
import com.ddstation.statement.model.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.ddstation.common.model.InvsCheckCommonSchParModel;
import com.ddstation.home_page.model.HpCommonParModel;
import com.ddstation.instrument_disinfect.model.InstrumentDisinfectResModel;
import com.ddstation.instrument_disinfect.service.InstrumentDisinfectService;
import com.ddstation.prescription_violate.model.InstitutionViolateResModel;
import com.ddstation.prescription_violate.service.PrescriptionViolateService;
import com.ddstation.sewage.model.SewageResModel;
import com.ddstation.sewage.model.SewageTestResModel;
import com.ddstation.sewage.model.SewageTestSearchParModel;
import com.ddstation.sewage.service.SewageService;
import com.ddstation.sewage.service.SewageTestReportService;
import com.ddstation.statement.mapper.StatisticsStatementMapper;
import com.ddstation.waste_delivery.model.WasteDeliveryResModel;
import com.ddstation.waste_delivery.service.WasteDeliveryService;

@Service
public class StatisticsStatementServiceImpl implements StatisticsStatementService {

    // 按 镇·街道 统计
    @Override
    @Transactional(readOnly = true)
    public List<IllegalInstitutionModel> searchIllegalInstitutionSum(
            CATALOG_ENUM _type, SearchParModel _inPar) {

        List<IllegalInstitutionModel> listout = null;

        switch (_type) {
            case PRESCRIPTION:// 处方
                listout = this.searchIllegalInstitutionprescription(_inPar);
                break;
            case SEWAGE_CHLORINE://污水余氯
                listout = this.searchIllegalInstitutionChlorine(_inPar);
                break;
            case SEWAGE_TEST_REPORT://污水检测报告
                listout = this.searchIllegalInstitutionSewageTestReport(_inPar);
                break;
            case WASTE_DELIVERY://医废处置
                listout = this.searchIllegalInstitutionWasteDelivery(_inPar);
                break;
            case INSTRUMENT_DISINFECT: //设备消毒:
                listout = this.searchIllegalInstitutionInstrumentDisinfect(_inPar);
                break;
            default:
                break;
        }
        return listout;
    }


    // 处方违规诊所数 按镇来统计
    private List<IllegalInstitutionModel> searchIllegalInstitutionprescription(SearchParModel _inPar) {

        // 查询所有的镇
        List<IllegalInstitutionModel> listout = this.searchIllegalInstitution(_inPar.getInvsInstitutionId());
        // 该卫监所没有管辖的镇（数据异常）
        if (listout == null || listout.size() == 0) {
            throw new RuntimeException("查询卫监所管辖的镇·街道 数据失败！卫监所id:" + _inPar.getInvsInstitutionId());
        }
        // 查询污水余氯状况
        InvsCheckCommonSchParModel _in = new InvsCheckCommonSchParModel();
        _in.setInvsInstitutionId(_inPar.getInvsInstitutionId());
        _in.setDtFrom(_inPar.getDateFrom());
        _in.setDtTo(_inPar.getDateTo());
        List<InstitutionViolateResModel> list = prescriptionViolateService.searchViolateCntGroupbyInstitutionId(_in);
        // 未查询数据
        if (list == null || list.size() == 0) {
            return listout;
        }

        for (IllegalInstitutionModel _a : listout) {
            List<InstitutionViolateResModel> fillerList = list.stream().filter(
                    a -> a.getTownId().equals(_a.getTownId()) && a.getViolateCnt() > 0)
                    .collect(Collectors.toList());
            if (fillerList == null || fillerList.size() == 0) {
                _a.setCount(0);
            } else {
                _a.setCount(fillerList.size());
            }
        }
        return listout;
    }

    // 污水余氯违规诊所数 按镇来统计
    private List<IllegalInstitutionModel> searchIllegalInstitutionChlorine(SearchParModel _inPar) {

        // 查询所有的镇
        List<IllegalInstitutionModel> listout = this.searchIllegalInstitution(_inPar.getInvsInstitutionId());
        // 该卫监所没有管辖的镇（数据异常）
        if (listout == null || listout.size() == 0) {
            throw new RuntimeException("查询卫监所管辖的镇·街道 数据失败！卫监所id:" + _inPar.getInvsInstitutionId());
        }
        // 查询污水余氯状况
        InvsCheckCommonSchParModel _in = new InvsCheckCommonSchParModel();
        _in.setInvsInstitutionId(_inPar.getInvsInstitutionId());
        _in.setDtFrom(_inPar.getDateFrom());
        _in.setDtTo(_inPar.getDateTo());
        List<SewageResModel> list = sewageService.searchInstitutionSewageList(_in);
        // 未查询数据
        if (list == null || list.size() == 0) {
            return listout;
        }

        for (IllegalInstitutionModel _a : listout) {
            List<SewageResModel> fillerList = list.stream().filter(a -> a.getTownId().equals(_a.getTownId())
                    && a.getCheckSt() == -1)
                    .collect(Collectors.toList());//找出这个镇 处方有违规数据的诊所
            if (fillerList == null || fillerList.size() == 0) {
                _a.setCount(0);
            } else {
                _a.setCount(fillerList.size());
            }
        }
        return listout;
    }

    /**
     * 污水检测报告 按镇来统计
     */
    private List<IllegalInstitutionModel> searchIllegalInstitutionSewageTestReport(SearchParModel _inPar) {

        // 查询所有的镇
        List<IllegalInstitutionModel> listout = this.searchIllegalInstitution(_inPar.getInvsInstitutionId());
        // 该卫监所没有管辖的镇（数据异常）
        if (listout == null || listout.size() == 0) {
            throw new RuntimeException("查询卫监所管辖的镇·街道 数据失败！卫监所id:" + _inPar.getInvsInstitutionId());
        }
        // 查询污水检测报告状况
        SewageTestSearchParModel _in = new SewageTestSearchParModel();
        _in.setInvsInstitutionId(_inPar.getInvsInstitutionId());
        _in.setDtFrom(_inPar.getDateFrom());
        _in.setDtTo(_inPar.getDateTo());
        List<SewageTestResModel> list = sewageTestReportService.searchSewageTestReportList(_in);
        // 未查询数据
        if (list == null || list.size() == 0) {
            return listout;
        }
        // 根据镇来过滤
        for (IllegalInstitutionModel _a : listout) {
            List<SewageTestResModel> fillerList = list.stream().filter(a -> a.getTownId().equals(_a.getTownId())).collect(Collectors.toList());

            if (fillerList == null || fillerList.size() == 0) {
                _a.setCount(0);
                continue;
            }

            _a.setCount(0);
        }
        return listout;
    }

    // 医废处置 按镇来统计
    private List<IllegalInstitutionModel> searchIllegalInstitutionWasteDelivery(SearchParModel _inPar) {

        // 查询所有的镇
        List<IllegalInstitutionModel> listout = this.searchIllegalInstitution(_inPar.getInvsInstitutionId());
        // 该卫监所没有管辖的镇（数据异常）
        if (listout == null || listout.size() == 0) {
            throw new RuntimeException("查询卫监所管辖的镇·街道 数据失败！卫监所id:" + _inPar.getInvsInstitutionId());
        }
        // 查询诊所医废处置
        InvsCheckCommonSchParModel _in = new InvsCheckCommonSchParModel();
        _in.setDtFrom(_inPar.getDateFrom());
        _in.setDtTo(_inPar.getDateTo());
        _in.setInvsInstitutionId(_inPar.getInvsInstitutionId());
        List<WasteDeliveryResModel> list = wasteDeliveryService.searchWasteDeliveryList(_in);
        // 未查询到违规数据
        if (list == null || list.size() == 0) {
            return listout;
        }

        for (IllegalInstitutionModel _a : listout) {
            List<WasteDeliveryResModel> fillerList = list.stream().filter(a -> a.getTownId().equals(_a.getTownId())
            )
                    .collect(Collectors.toList());
            if (fillerList == null || fillerList.size() == 0) {
                _a.setCount(0);
            } else {
                _a.setCount(fillerList.size());
            }
        }
        return listout;
    }

    // 器械消毒 按镇来统计
    private List<IllegalInstitutionModel> searchIllegalInstitutionInstrumentDisinfect(SearchParModel _inPar) {

        // 查询所有的镇
        List<IllegalInstitutionModel> listout = this.searchIllegalInstitution(_inPar.getInvsInstitutionId());
        // 该卫监所没有管辖的镇（数据异常）
        if (listout == null || listout.size() == 0) {
            throw new RuntimeException("查询卫监所管辖的镇·街道 数据失败！卫监所id:" + _inPar.getInvsInstitutionId());
        }
        // 器械消毒查询
        InvsCheckCommonSchParModel _in = new InvsCheckCommonSchParModel();
        _in.setDtFrom(_inPar.getDateFrom());
        _in.setDtTo(_inPar.getDateTo());
        _in.setInvsInstitutionId(_inPar.getInvsInstitutionId());
        List<InstrumentDisinfectResModel> list = instrumentDisinfectService.searchInstrumentDisinfectList(_in);
        // 未查询到违规数据
        if (list == null || list.size() == 0) {
            return listout;
        }
        // 只取异常的数据
        list = list.stream().filter(
                a -> a.getCheckSt().intValue() == -1)
                .collect(Collectors.toList());
        if (list == null || list.size() == 0) {
            return listout;
        }

        for (IllegalInstitutionModel _a : listout) {
            List<InstrumentDisinfectResModel> fillerList = list.stream().filter(
                    a -> a.getTownId().equals(_a.getTownId()))
                    .collect(Collectors.toList());
            if (fillerList == null || fillerList.size() == 0) {
                _a.setCount(0);
            } else {
                _a.setCount(fillerList.size());
            }
        }
        return listout;
    }

    // 按 违规种类 统计
    @Override
    @Transactional(readOnly = true)
    public List<IllegalTypeModel> searchIllegalTypeSum(CATALOG_ENUM _type, SearchParModel _in) {
        List<IllegalTypeModel> listout = new ArrayList<IllegalTypeModel>();

        switch (_type) {
            case PRESCRIPTION:// 处方
                return searchIllegalTypePrescription(_in);
            case SEWAGE_CHLORINE://污水余氯
                return this.searchIllegalTypeChlorine(_in);
            case SEWAGE_TEST_REPORT://污水检测报告
                return this.searchIllegalTypeTestReport(_in);
            case WASTE_DELIVERY://医废处置
            case INSTRUMENT_DISINFECT: //设备消毒:
                IllegalTypeModel _a = new IllegalTypeModel();
                _a.setIllegalTypeName("多日未登记");
                _a.setCount(1);
                listout.add(_a);
                break;
            default:
                break;
        }
        return listout;
    }

    /**
     * 处方 违规类型  统计
     */
    private List<IllegalTypeModel> searchIllegalTypePrescription(SearchParModel _inPar) {
        HpCommonParModel _p = new HpCommonParModel();
        _p.setInvsInstitutionId(_inPar.getInvsInstitutionId());
        _p.setDtFrom(_inPar.getDateFrom());
        _p.setDtTo(_inPar.getDateTo());
        return prescriptionViolateService.searchIllegalTypePrescription(_p);
    }

    /**
     * 污水余氯按 违规类型  统计
     */
    private List<IllegalTypeModel> searchIllegalTypeChlorine(SearchParModel _inPar) {
        // 返回值
        List<IllegalTypeModel> listout = new ArrayList<>();
        // 查询污水余氯状况
        InvsCheckCommonSchParModel _in = new InvsCheckCommonSchParModel();
        _in.setInvsInstitutionId(_inPar.getInvsInstitutionId());
        _in.setDtFrom(_inPar.getDateFrom());
        _in.setDtTo(_inPar.getDateTo());
        List<SewageResModel> list = sewageService.searchInstitutionSewageList(_in);
        // 未查询数据
        if (list == null || list.size() == 0) {
            return listout;
        }
        // 分类1：余氯未登记数
        IllegalTypeModel _oneType = new IllegalTypeModel();
        int count = 0;
//		List<SewageResModel> fillerlist = list.stream().filter(a->a.getRegistryStatus().intValue() == -1).collect(Collectors.toList());
//		if (fillerlist !=null ){
//			count = fillerlist.size();
//		}
        _oneType.setCount(count);
        _oneType.setIllegalTypeName("多日未登记");
        listout.add(_oneType);
        // 分类2：余氯超标数
        _oneType = new IllegalTypeModel();
        _oneType.setCount(count);
        _oneType.setIllegalTypeName("结果超标");
        listout.add(_oneType);

        return listout;
    }

    /**
     * 污水检测报告按 违规类型  统计
     */
    private List<IllegalTypeModel> searchIllegalTypeTestReport(SearchParModel _inPar) {
        // 返回值
        List<IllegalTypeModel> listout = new ArrayList<>();
        // 查询污水检测报告状况
        // 查询污水检测报告状况
        SewageTestSearchParModel _in = new SewageTestSearchParModel();
        _in.setInvsInstitutionId(_inPar.getInvsInstitutionId());
        _in.setDtFrom(_inPar.getDateFrom());
        _in.setDtTo(_inPar.getDateTo());
        List<SewageTestResModel> list = sewageTestReportService.searchSewageTestReportList(_in);
        // 未查询数据
        if (list == null || list.size() == 0) {
            return listout;
        }
        // 分类1：检测报告未登记数
        IllegalTypeModel _oneType = new IllegalTypeModel();
        int count = 0;
//		List<SewageTestResModel> fillerlist = list.stream().filter(a->a.getRegistryStatus().intValue() == -1).collect(Collectors.toList());
//		if (fillerlist !=null ){
//			count = fillerlist.size();
//		}
//		_oneType.setCount(count);
//		_oneType.setIllegalTypeName("未登记");
//		listout.add(_oneType);
//		// 分类2：报告不合格
//		fillerlist = list.stream().filter(a->
//				a.getUploadEntity()!=null && 
//				a.getUploadEntity().getQualifiedFlg() != null && 
//				a.getUploadEntity().getQualifiedFlg().intValue() == 2)
//				.collect(Collectors.toList());
//		if (fillerlist !=null ){
//			count = fillerlist.size();
//		}
        _oneType = new IllegalTypeModel();
        _oneType.setCount(count);
        _oneType.setIllegalTypeName("报告不合格");
        listout.add(_oneType);

        return listout;
    }

    /**
     * 查询卫监所下所有的镇
     */
    @Override
    @Transactional(readOnly = true)
    public List<IllegalInstitutionModel> searchIllegalInstitution(String invsInstitutionId) {
        return statisticsStatementMapper.selectTownList(invsInstitutionId);
    }

    /**
     * 首页：查询期间内异常机构的数量
     */
    @Override
    @Transactional(readOnly = true)
    public int getAbnormalInstitutionCnt(SearchParModel _in) {
        Set<String> institutions = new HashSet<>();//记录异常的机构列表

        // 医疗废弃物
        InvsCheckCommonSchParModel _wdPar = new InvsCheckCommonSchParModel();
        _wdPar.setInvsInstitutionId(_in.getInvsInstitutionId());
        _wdPar.setDtFrom(_in.getDateFrom());
        _wdPar.setDtTo(_in.getDateTo());
        List<WasteDeliveryResModel> datalist = wasteDeliveryService.searchWasteDeliveryList(_wdPar);
        for (WasteDeliveryResModel a : datalist) {
            institutions.add(a.getInstitutionId());
        }
        // 设备消毒
        InvsCheckCommonSchParModel _idPar = new InvsCheckCommonSchParModel();
        _idPar.setInvsInstitutionId(_in.getInvsInstitutionId());
        _idPar.setDtFrom(_in.getDateFrom());
        _idPar.setDtTo(_in.getDateTo());
        List<InstrumentDisinfectResModel> _idList = instrumentDisinfectService.searchInstrumentDisinfectList(_idPar);
        for (InstrumentDisinfectResModel a : _idList) {
            institutions.add(a.getInstitutionId());
        }
        // 污水检测报告
        SewageTestSearchParModel repPar = new SewageTestSearchParModel();
        repPar.setInvsInstitutionId(_in.getInvsInstitutionId());
        repPar.setDtFrom(_in.getDateFrom());
        repPar.setDtTo(_in.getDateTo());
        List<SewageTestResModel> repList = sewageTestReportService.searchSewageTestReportList(repPar);
        for (SewageTestResModel a : repList) {
            institutions.add(a.getInstitutionId());
        }
        // 污水余氯
        InvsCheckCommonSchParModel _sePar = new InvsCheckCommonSchParModel();
        _sePar.setInvsInstitutionId(_in.getInvsInstitutionId());
        _sePar.setDtFrom(_in.getDateFrom());
        _sePar.setDtTo(_in.getDateTo());
        List<SewageResModel> seList = sewageService.searchInstitutionSewageList(_sePar);
        for (SewageResModel a : seList) {
            institutions.add(a.getInstitutionId());
        }

        return institutions.size();
    }

    @Override
    public PieStatisticDisplayModel getPieStatistic(String invsInstitutionId, Date startDt, Date endDt) {
        PieStatisticDisplayModel pieStatisticDisplayModel = new PieStatisticDisplayModel();
        pieStatisticDisplayModel.setInstitutionCnt(statisticsStatementMapper.countUnderINVSHealthInstitutions(invsInstitutionId));
        pieStatisticDisplayModel.setDisinfectCnt(statisticsStatementMapper.countDisinfectInstitutions(invsInstitutionId, startDt, endDt));
        pieStatisticDisplayModel.setMedicalHisCnt(statisticsStatementMapper.countEleMedicalHisHealthInstitutions(invsInstitutionId, startDt, endDt));
        pieStatisticDisplayModel.setPrescriptionCnt(pieStatisticDisplayModel.getMedicalHisCnt());
        return pieStatisticDisplayModel;
    }

    @Override
    public List<TableStatisticItemModel> getClinicStatistic(String invsInstitutionId, Date startDt, Date endDt) {
        List<TableStatisticItemModel> resultList = new ArrayList<>();

        TableStatisticItemModel medicalHisItem = new TableStatisticItemModel();
        medicalHisItem.setName("开具电子病历数");
        medicalHisItem.setValue(statisticsStatementMapper.countMedicalHisByDuration(invsInstitutionId, startDt, endDt));
        resultList.add(medicalHisItem);

        TableStatisticItemModel prescriptionItem = new TableStatisticItemModel();
        prescriptionItem.setName("开具电子处方数");
        prescriptionItem.setValue(statisticsStatementMapper.countPrescriptionByDuration(invsInstitutionId, startDt, endDt));
        resultList.add(prescriptionItem);

        TableStatisticItemModel medicineItem = new TableStatisticItemModel();
        medicineItem.setName("录入药品数");
        medicineItem.setValue(statisticsStatementMapper.countMedicines(invsInstitutionId, startDt, endDt));
        resultList.add(medicineItem);

        return resultList;
    }

    @Override
    public List<TableStatisticItemModel> getErrorStatistic(String invsInstitutionId, Date startDt, Date endDt) {
        List<TableStatisticItemModel> resultList = new ArrayList<>();

        TableStatisticItemModel qualificationItem = new TableStatisticItemModel();
        qualificationItem.setName("资质审查违规数");
        List<String> msgIdList = new ArrayList<>(Arrays.asList("820001", "820002", "810002", "820003", "820004", "820005"));
        qualificationItem.setValue(statisticsStatementMapper.countErrorWithMSGId(invsInstitutionId, msgIdList, startDt, endDt));
        resultList.add(qualificationItem);

        TableStatisticItemModel medicalHisErrorItem = new TableStatisticItemModel();
        medicalHisErrorItem.setName("病历违规数");
        msgIdList.clear();
        msgIdList.add("810001");
        medicalHisErrorItem.setValue(statisticsStatementMapper.countErrorWithMSGId(invsInstitutionId, msgIdList, startDt, endDt));
        resultList.add(medicalHisErrorItem);

        TableStatisticItemModel prescriptionErrorItem = new TableStatisticItemModel();
        prescriptionErrorItem.setName("处方违规数");
        msgIdList.clear();
        msgIdList.addAll(Arrays.asList("810003", "840001", "840002", "840003", "840004", "840005", "840006", "840007", "840008"));
        prescriptionErrorItem.setValue(statisticsStatementMapper.countErrorWithMSGId(invsInstitutionId, msgIdList, startDt, endDt));
        resultList.add(prescriptionErrorItem);

        // 台账异常查询
        List<TableStatisticItemModel> disinfectList = statisticsStatementMapper.countDisinfectDetail(invsInstitutionId, startDt, endDt);
        for (IllegalDailyCheckEnum illegalDailyCheckEnum : IllegalDailyCheckEnum.values()) {
            TableStatisticItemModel selectItem = null;
            for (TableStatisticItemModel item : disinfectList) {
                if (item.getType() == illegalDailyCheckEnum.getSubTypeCode()) {
                    selectItem = item;
                    item.setName(illegalDailyCheckEnum.getName());
                    resultList.add(item);
                }
            }
            if (null == selectItem) {
                selectItem = new TableStatisticItemModel();
                selectItem.setName(illegalDailyCheckEnum.getName());
                selectItem.setValue(0);
                selectItem.setType(illegalDailyCheckEnum.getSubTypeCode());
                resultList.add(selectItem);
            }
        }
        return resultList;
    }

    @Override
    public HashMap getStatisticsData(HpCommonParModel _p) {
        HashMap ret = new HashMap();

        //已监管、未监管机构数量
        HashMap isInvsList = statisticsStatementMapper.getInstitutionCountListByIsInvs(_p);
        ret.put("isInvsList", isInvsList);

        //医疗机构资质已过期数量
        Integer overdueCnt = statisticsStatementMapper.getOverdueInstitutionCount(_p);
        ret.put("overdueCnt", overdueCnt);

        //已监管、未监管机构数量
        Integer invsDoctorCnt = statisticsStatementMapper.getInvsDoctorsCount(_p);
        ret.put("invsDoctorCnt", invsDoctorCnt);

        _p.setUnderInvs(1);
        //监管机构分布  根据公立、民营
        HashMap attrList = statisticsStatementMapper.getDistributionByInstitutionAttr(_p);
        ret.put("attrList", attrList);

        //监管机构分布  根据机构类型一级目录
        List<NameValueModel> firstTypeList = statisticsStatementMapper.getDistributionByInstitutionTypeFirst(_p);
        ret.put("firstTypeList", firstTypeList);

        //执业医师分布 公立、民营数量
        HashMap doctorsDistribution = statisticsStatementMapper.getDoctorsDistribution(_p);
        ret.put("doctorsDistribution", doctorsDistribution);

        //获取 电子处方累计监管、违规、申诉、未申诉数量, 卫生台账累计监管、异常、申诉、未申诉数量
        HashMap statistics = statisticsStatementMapper.getAccountAndPrescriptionStatistics(_p);
        ret.put("statistics", statistics);

        //获取 电子病历数量
        Integer medicalHisCnt = statisticsStatementMapper.getMedicalHisCount(_p);
        ret.put("medicalHisCnt", medicalHisCnt);

        //获取 电子处方数量
        _p.setPrescriptionInvs(1);
        Integer prescriptionCnt = statisticsStatementMapper.statisticsDailyPrescription(_p);
        ret.put("prescriptionCnt", prescriptionCnt);
        _p.setPrescriptionInvs(null);

        Integer[] pTypes = {40};
        Integer[] aTypes = {10,20,30};
        _p.setLimit(10);
        //获取机构处方违规数量排行
        _p.setPrescriptionInvs(1);
        _p.setBusinessTypeList(pTypes);
        List<HashMap> preIllegalList = statisticsStatementMapper.getInstitutionIllegalList(_p, 2);
        _p.setPrescriptionInvs(null);
        ret.put("preIllegalList", preIllegalList);

        //获取机构台账违规数量排行
        _p.setBusinessTypeList(aTypes);
        List<HashMap> accIllegalList = statisticsStatementMapper.getInstitutionIllegalList(_p, 1);
        ret.put("accIllegalList", accIllegalList);

        return ret;
    }

    @Inject
    private WasteDeliveryService wasteDeliveryService;
    @Inject
    private InstrumentDisinfectService instrumentDisinfectService;
    @Inject
    private StatisticsStatementMapper statisticsStatementMapper;
    @Inject
    private SewageService sewageService;
    @Inject
    private SewageTestReportService sewageTestReportService;
    @Inject
    private PrescriptionViolateService prescriptionViolateService;
}
